package fiveGame.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.Optional;
import java.util.function.Predicate;

import fiveGame.Util.StaticTool;
import fiveGame.element.Chesses;
import fiveGame.element.SaveElement;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceDialog;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

/**
 * 
 * @author Tiangle
 * 
 * @version 创建时间：2021年9月10日 上午11:42:51
 * 
 * 
 * 
 */
public class UI extends Application {
	LinkedList<Chesses> ch = new LinkedList<Chesses>();
	public int isBlack = 1;
	public int blackr = 0;
	public int whiter = 0;
	public int canRe = 0;
	public boolean win = false;
	File f = new File("src\\save");

	@Override
	public void start(Stage primaryStage) throws Exception {
		// TODO Auto-generated method stub
		Pane p = new Pane();
		Scene scene = new Scene(p, 600, 640);

		for (int j = StaticTool.firstY; j <= StaticTool.xyLen * StaticTool.yLength; j += StaticTool.xyLen) {
			p.getChildren()
					.add(new Line(StaticTool.firstX, j, StaticTool.xyLen * StaticTool.xLength - StaticTool.firstX, j));
		}
		for (int i = StaticTool.firstX; i <= StaticTool.xyLen * StaticTool.xLength; i += StaticTool.xyLen) {
			p.getChildren()
					.add(new Line(i, StaticTool.firstY, i, StaticTool.xyLen * StaticTool.yLength - StaticTool.firstY));
		}
		primaryStage.setScene(scene);
		primaryStage.setResizable(false);
		primaryStage.show();
		Background bg = new Background(new BackgroundFill(Color.BISQUE,null,null));
		p.setBackground(bg);
		Button button1 = new Button("开始");
		button1.setPrefSize(80, 40);
		button1.setLayoutX(20);
		button1.setLayoutY(600);
		p.getChildren().add(button1);
		
		button1.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				// TODO Auto-generated method stub
				p.getChildren().removeIf(new Predicate<Object>(){
				
					@Override
					public boolean test(Object t) {
						// TODO Auto-generated method stub
						return t instanceof Circle;
					}
				});
				ch.removeAll(ch);
				isBlack = 1;
				blackr = 0;
				whiter = 0;
				canRe = 0;
				win = false;
			}
			
		});

		Button button2 = new Button("悔棋");
		button2.setPrefSize(80, 40);
		button2.setLayoutX(120);
		button2.setLayoutY(600);
		p.getChildren().add(button2);
		
		button2.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				// TODO Auto-generated method stub
				if(revoke()) {
					p.getChildren().remove(p.getChildren().size()-1);
					reee();
				}else {
					Alert alert = new Alert(AlertType.WARNING);
					alert.setTitle("不准悔棋");
					alert.setHeaderText("点击确定继续");
					if(win) {
						alert.setContentText("胜负已分！");
					}else {
						alert.setContentText(((isBlack == 2&&blackr<StaticTool.re)||(isBlack==1&&whiter<StaticTool.re))?"不能连续悔棋或者第一步悔棋":"最多悔棋"+StaticTool.re+"次！");
					}
					
					alert.show();
				}
				
				
				
				
			}
			
		});

		Button button3 = new Button("保存");
		button3.setPrefSize(80, 40);
		button3.setLayoutX(220);
		button3.setLayoutY(600);
		p.getChildren().add(button3);
		
		button3.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				// TODO Auto-generated method stub
				if(ch.size()!=0) {
					try {
						String s = save();
						Alert alert = new Alert(AlertType.INFORMATION);
						alert.setTitle("保存棋局");
						alert.setHeaderText("保存成功！");
						alert.setContentText("保存文件为："+s);
						alert.show();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}else {
					Alert alert = new Alert(AlertType.WARNING);
					alert.setTitle("保存棋局");
					alert.setHeaderText("游戏还未开始");
					alert.setContentText("没开始你保存个屁");
					alert.show();
				}
				
			}
			
		});

		Button button4 = new Button("读取");
		button4.setPrefSize(80, 40);
		button4.setLayoutX(320);
		button4.setLayoutY(600);
		p.getChildren().add(button4);
		
		button4.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				ArrayList<String> fileNames = getFileName();
				if(fileNames.size()==0) {
					Alert alert = new Alert(AlertType.WARNING);
					alert.setTitle("读取棋局");
					alert.setHeaderText("没有存档");
					alert.setContentText("没有存档你读取个屁");
					alert.show();
					return;
				}
				
				Alert alert = new Alert(AlertType.CONFIRMATION);
				alert.setTitle("读取棋谱");
				alert.setHeaderText("确定开始吗？");
				alert.setContentText("一旦按下确定，现有棋局将不会自动保存");
				Optional<ButtonType> answer = alert.showAndWait();
				if(answer.get()==ButtonType.OK) {
					
					ChoiceDialog<String> cs = new ChoiceDialog<String>(fileNames.get(0),fileNames);
					cs.setTitle("请选择已有存档");
					cs.setHeaderText("选择存档以继续");
					cs.setContentText("读档：");
					Optional<String> os = cs.showAndWait();
					String str = null;
					try{str = os.get();
					}catch(Exception e) {
						return;
					} 
					try {
						
						old(str);
					} catch (ClassNotFoundException | IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					p.getChildren().removeIf(new Predicate<Object>(){
						
						@Override
						public boolean test(Object t) {
							// TODO Auto-generated method stub
							return t instanceof Circle;
						}
					});
					for(Chesses c:ch) {
						p.getChildren().add(new Circle(c.getX(),c.getY(), 20, c.getColor() == 1 ? Color.BLACK : Color.WHITE));
					}
					
					
				}
			}
			
		});

		

		Button button5 = new Button("退出");
		button5.setPrefSize(80, 40);
		button5.setLayoutX(520);
		button5.setLayoutY(600);
		p.getChildren().add(button5);
		
		button5.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				// TODO Auto-generated method stub
				Alert alert = new Alert(AlertType.CONFIRMATION);
				alert.setTitle("退出游戏");
				alert.setHeaderText("确定退出吗？");
				alert.setContentText("一旦按下确定，现有棋局将不会自动保存");
				Optional<ButtonType> answer = alert.showAndWait();
				if(answer.get()==ButtonType.OK) {System.exit(0);}
			}});
		Button button6 = new Button("清空缓存");
		button6.setPrefSize(80, 40);
		button6.setLayoutX(420);
		button6.setLayoutY(600);
		p.getChildren().add(button6);
		button6.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				// TODO Auto-generated method stub
				if(getFileName().size()==0) {
					Alert alert = new Alert(AlertType.WARNING);
					alert.setTitle("清空缓存");
					alert.setHeaderText("没有存档");
					alert.setContentText("没有存档你清空个屁");
					alert.show();
					return;
				}
				Alert alert = new Alert(AlertType.CONFIRMATION);
				alert.setTitle("清空缓存");
				alert.setHeaderText("确定清除吗？");
				alert.setContentText("一旦按下确定，保存的所有棋局将会删除");
				Optional<ButtonType> answer = alert.showAndWait();
				if(answer.get()==ButtonType.OK) {
					delete();
					Alert alert2 = new Alert(AlertType.WARNING);
					alert2.setTitle("清空缓存");
					alert2.setHeaderText("删完了");
					alert2.setContentText("没有存档了");
					alert2.show();
				}
			}});
		
		
		
		p.setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				// TODO Auto-generated method stub
				if(win) {
					Alert alert = new Alert(AlertType.INFORMATION);
					alert.setTitle("游戏结束");
					alert.setHeaderText("胜利！");
					alert.setContentText((isBlack == 2 ?"黑的":"白的")+"赢了");
					alert.show();
					return;
				}
				int x = (int) event.getX();
				int y = (int) event.getY();
				Chesses c = getC(x, y);

				if (hasChess(c)) {
					Alert alert = new Alert(AlertType.WARNING);
					alert.setTitle("重复棋子");
					alert.setHeaderText("已有棋子");
					alert.setContentText("请重新下子");
					alert.show();
				} else {
					c.setColor(isBlack);
					ch.addLast(c);
					canRe++;
					if (isBlack == 1)
						isBlack = 2;
					else
						isBlack = 1;
					Circle c1 = new Circle(c.getX(), c.getY(), 20, c.getColor() == 1 ? Color.BLACK : Color.WHITE);
					p.getChildren().add(c1);
					
					if(isWin(c)) {
						Alert alert = new Alert(AlertType.INFORMATION);
						alert.setTitle("游戏结束");
						alert.setHeaderText("胜利！");
						alert.setContentText((isBlack == 2 ?"黑的":"白的")+"赢了");
						alert.show();
						win = true;
					}
					
				}

			}
		});
	}

	public Chesses getC(int x, int y) {
		int x1 = (x - StaticTool.firstX) / StaticTool.xyLen;
		int y1 = (y - StaticTool.firstY) / StaticTool.xyLen;
		if ((x - StaticTool.firstX) % StaticTool.xyLen >= StaticTool.xyLen / 2) {
			x1 = (x1 + 1) * StaticTool.xyLen + StaticTool.firstX;
		} else {
			x1 = x1 * StaticTool.xyLen + StaticTool.firstX;
		}
		if ((y - StaticTool.firstY) % StaticTool.xyLen >= StaticTool.xyLen / 2) {
			y1 = (y1 + 1) * StaticTool.xyLen + StaticTool.firstY;
		} else {
			y1 = y1 * StaticTool.xyLen + StaticTool.firstY;
		}
		return new Chesses(x1, y1);
	}

	public Chesses move(Chesses c, int x, int y) {
		Chesses cc = new Chesses(c.getX() + StaticTool.xyLen * x, c.getY() + y * StaticTool.xyLen);
		if (hasChess(cc)) {
			return getChess(cc.getX(), cc.getY());
		}
		return null;
	}

	public boolean hasChess(Chesses c) {
		// TODO Auto-generated method stub
		if (ch == null)
			return false;
		for (Chesses x : ch) {
			if (c.equals(x)) {
				return true;
			}
		}
		return false;
	}

	public Chesses getChess(int x, int y) {
		if (ch == null)
			return null;
		for (Chesses a : ch) {
			if (a.equals(new Chesses(x, y))) {
				return a;
			}
		}
		return null;
	}
	
	public boolean isWin(Chesses c) {
		// TODO Auto-generated method stub
		int h = 1;
		int s = 1;
		int p = 1;
		int l = 1;
		for (int i = 1; i < 5; i++) {
			if (move(c, i, 0) == null)
				break;
			if (move(c, i, 0).getColor() == c.getColor()) {
				h++;
			} else {
				break;
			}
		}
		for (int i = -1; i > -5; i--) {
			if (move(c, i, 0) == null)
				break;
			if (move(c, i, 0).getColor() == c.getColor()) {
				h++;
			} else {
				break;
			}
		}
		for (int i = 1; i < 5; i++) {
			if (move(c, 0, i) == null)
				break;
			if (move(c, 0, i).getColor() == c.getColor()) {
				s++;
			} else {
				break;
			}
		}
		for (int i = -1; i > -5; i--) {
			if (move(c, 0, i) == null)
				break;
			if (move(c, 0, i).getColor() == c.getColor()) {
				s++;
			} else {
				break;
			}
		}
		for (int i = 1; i < 5; i++) {
			if (move(c, i, i) == null)
				break;
			if (move(c, i, i).getColor() == c.getColor()) {
				p++;
			} else {
				break;
			}
		}
		for (int i = -1; i > -5; i--) {
			if (move(c, i, i) == null)
				break;
			if (move(c, i, i).getColor() == c.getColor()) {
				p++;
			} else {
				break;
			}
		}
		for (int i = 1; i < 5; i++) {
			if (move(c, -i, i) == null)
				break;
			if (move(c, -i, i).getColor() == c.getColor()) {
				l++;
			} else {
				break;
			}
		}
		for (int i = -1; i > -5; i--) {
			if (move(c, -i, i) == null)
				break;
			if (move(c, -i, i).getColor() == c.getColor()) {
				l++;
			} else {
				break;
			}
		}
		if (h >= 5 || s >= 5 || p >= 5||l>=5) {
			return true;
		}

		System.out.println("h:" + h + "\ns:" + s + "\np:" + p);
		return false;
	}
	
	public boolean revoke() {
		// TODO Auto-generated method stub

		if (((isBlack == 2&&blackr<StaticTool.re)||(isBlack==1&&whiter<StaticTool.re))&&canRe>=2&&!win) {
			return true;
		}
		return false;
	}
	public void reee() {
		ch.removeLast();
		if (isBlack == 1) {
			whiter++;
			isBlack = 2;
		}
			
		else {
			isBlack = 1;
			blackr++;
		}
			
		canRe = 0;
	}
	public String save() throws IOException {
		String s = getName();
		File ff = new File(f,"Chesses_"+s+".txt");
		ff.createNewFile();
		FileOutputStream fs = new FileOutputStream(ff);
		ObjectOutputStream os = new ObjectOutputStream(fs);
		SaveElement se = new SaveElement(this.ch,isBlack,blackr,whiter,canRe,win);
		os.writeObject(se);
		os.close();
		fs.close();
		return ff.getName();
		
	}
	public String getName() {
		String s = "";
		Date d = new Date();
		SimpleDateFormat sd = new SimpleDateFormat("MM月dd日HH点mm分ss秒的棋局");
		
		s = sd.format(d);
		System.out.println(s);
		return s;
	}
	public ArrayList<String> getFileName(){
		ArrayList<String> al = new ArrayList<>();
		String[] ss = f.list();
		for(String s:ss) {
			if(s.startsWith("Chesses_")) {
				al.add(s);
			}
		}
		return al;
	}
	public void old(String s) throws IOException, ClassNotFoundException {
		File ff = new File(f,s);
		FileInputStream fs = new FileInputStream(ff);
		ObjectInputStream os = new ObjectInputStream(fs);
		SaveElement c = (SaveElement) os.readObject();
		flush(c);
		os.close();
		fs.close();
	}
	public void delete() {
		String[] ss = f.list();
		for(String s:ss) {
			File ff = new File(f,s);
			ff.delete();
		}
	}
	public void flush(SaveElement c) {
		this.ch = c.ch;
		this.blackr = c.blackr;
		this.whiter = c.whiter;
		this.isBlack = c.isBlack;
		this.canRe = c.canRe;
		this.win = c.win;
	}
}
